package com.sunny.blog.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sunny.blog.common.entity.MessageConst;
import com.sunny.blog.common.entity.SysConstant;
import com.sunny.blog.mapper.BloggerInfoMapper;
import com.sunny.blog.mapper.CommentUserMapper;
import com.sunny.blog.mapper.UserInfoMapper;
import com.sunny.blog.pojo.BloggerInfoBean;
import com.sunny.blog.pojo.CommentUserBean;
import com.sunny.blog.pojo.LoginReqBean;
import com.sunny.blog.pojo.UserInfoBean;
import com.sunny.blog.service.ICacheService;
import com.sunny.blog.service.UserInfoService;
import com.sunny.blog.util.AesUtil;
import com.sunny.blog.util.CommonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @ClassName: UserInfoServiceImpl
 * @Description:
 * @Author: sunt
 * @Date: 2020/4/13 9:56
 * @Version 1.0
 **/
@Service
public class UserInfoServiceImpl implements UserInfoService {

    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private ICacheService cacheService;
    @Autowired
    private BloggerInfoMapper bloggerInfoMapper;
    @Autowired
    private CommentUserMapper commentUserMapper;

    @Override
    public List<UserInfoBean> queryAllUser() {
        return userInfoMapper.selectList(null);
    }

    @Override
    public JSONObject doLogin(LoginReqBean loginReqBean) {
        JSONObject jsonObject = new JSONObject();
        String encryptKey = loginReqBean.getEncryptKey();
        String userName = AesUtil.deCode(loginReqBean.getUserName(), encryptKey);
        String passWord = AesUtil.deCode(loginReqBean.getPassWord(), encryptKey);
        String verifyCode = AesUtil.deCode(loginReqBean.getVerifyCode(), encryptKey);
        //登录校验
        if(ObjectUtil.isNull(loginReqBean)) {
            jsonObject.put("errorMsg","非法请求");
            return jsonObject;
        }
        if(StrUtil.isBlank(userName)) {
            jsonObject.put("errorMsg","请输入用户名");
            return jsonObject;
        }
        if(StrUtil.isBlank(passWord)) {
            jsonObject.put("errorMsg","请输入密码");
            return jsonObject;
        }
        if(StrUtil.isBlank(verifyCode)) {
            jsonObject.put("errorMsg","请输入验证码");
            return jsonObject;
        }
        //业务校验
        String cacheVerCode =  cacheService.getCacheInfoByCode(verifyCode.toUpperCase());
        if(StrUtil.isBlank(cacheVerCode)) {
            jsonObject.put("errorMsg","请输入正确的验证码!");
            return jsonObject;
        }
        if(!StrUtil.equalsAnyIgnoreCase(verifyCode, cacheVerCode)) {
            jsonObject.put("errorMsg","请输入正确的验证码");
            return jsonObject;
        }
        UserInfoBean userInfoBean = queryUserByName(userName);
        if(ObjectUtil.isNull(userInfoBean)) {
            jsonObject.put("errorMsg","请输入正确的用户名和密码");
            return jsonObject;
        }
        //密码加密
        String inputPwd = SecureUtil.md5(passWord + MessageConst.PASSWORD_SALT);
        if(!StrUtil.equals(inputPwd, userInfoBean.getPassWord())) {
            jsonObject.put("errorMsg","请输入正确的用户名和密码");
            return jsonObject;
        }

        //校验通过生成token
        String loginToken = SecureUtil.md5(userInfoBean.getUserName() + IdUtil.fastSimpleUUID().toLowerCase());
        //登录信息加入到缓存
        cacheService.cacheObjData(loginToken, userInfoBean, 120);
        jsonObject.put("loginToken",loginToken);
        return jsonObject;
    }

    @Override
    public UserInfoBean getLoginInfo(String token) {
        return null;
    }

    @Override
    @Cacheable(value = SysConstant.USER_CACHE,key = "#userName",unless = "#result == null")
    public UserInfoBean queryUserByName(String userName) {
        QueryWrapper<UserInfoBean> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_NAME",userName);
        return userInfoMapper.selectOne(queryWrapper);
    }

    @Override
    @Cacheable(value = SysConstant.BLOGGER_INFO_CACHE,unless = "#result == null")
    public List<BloggerInfoBean> queryBloggerInfo(String userId) {
        QueryWrapper<BloggerInfoBean> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_ID",userId);
        queryWrapper.eq("IS_ENABLE", MessageConst.ENABLED);
        return bloggerInfoMapper.selectList(queryWrapper);
    }

    @Override
    public JSONObject userLogin(CommentUserBean loginReqBean) {
        JSONObject jsonObject = new JSONObject();
        //登录校验
        if(ObjectUtil.isNull(loginReqBean)) {
            jsonObject.put("errorMsg","非法登录");
            return jsonObject;
        }
        if(StrUtil.isBlank(loginReqBean.getUserEmail())) {
            jsonObject.put("errorMsg","请输入邮件账号");
            return jsonObject;
        }
        if(StrUtil.isBlank(loginReqBean.getPassWord())) {
            jsonObject.put("errorMsg","请输入密码");
            return jsonObject;
        }
        if(StrUtil.isBlank(loginReqBean.getVerifyCode())) {
            jsonObject.put("errorMsg","请输入验证码");
            return jsonObject;
        }
        //业务校验
        String cacheVerCode =  cacheService.getCacheInfoByCode(loginReqBean.getVerifyCode().toUpperCase());
        if(StrUtil.isBlank(cacheVerCode)) {
            jsonObject.put("errorMsg","验证码错误或已过期");
            return jsonObject;
        }
        if(!StrUtil.equalsAnyIgnoreCase(loginReqBean.getVerifyCode(), cacheVerCode)) {
            jsonObject.put("errorMsg","验证码错误或已过期");
            return jsonObject;
        }
        CommentUserBean bean = queryCommentUser(loginReqBean.getUserEmail());
        if(ObjectUtil.isNull(bean)) {
            jsonObject.put("errorMsg","用户名或密码错误");
            return jsonObject;
        }
        //密码加密
        String inputPwd = SecureUtil.md5(loginReqBean.getPassWord() + MessageConst.PASSWORD_SALT);
        if(!StrUtil.equals(inputPwd, bean.getPassWord())) {
            jsonObject.put("errorMsg","用户名或密码错误");
            return jsonObject;
        }

        //校验通过生成token
        String loginToken = SecureUtil.md5(bean.getUserEmail() + IdUtil.fastSimpleUUID().toLowerCase());
        //登录信息加入到缓存
        cacheService.cacheObjData(loginToken, bean, 24*60);
        jsonObject.put("loginToken",loginToken);
        return jsonObject;
    }

    @Override
    public CommentUserBean queryCommentUser(String userName) {
        QueryWrapper<CommentUserBean> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_EMAIL",userName);
        queryWrapper.eq("USER_STATE",MessageConst.ENABLED);
        return commentUserMapper.selectOne(queryWrapper);
    }

    @Override
    @Transactional
    public void insertCommentUser(CommentUserBean commentUserBean) {
        commentUserBean.setUserId(CommonUtil.genId());
        commentUserBean.setPassWord(SecureUtil.md5(commentUserBean.getPassWord() + MessageConst.PASSWORD_SALT));
        commentUserBean.setUserState(MessageConst.ENABLED);
        commentUserBean.setStartTime(DateUtil.date());
        commentUserMapper.insert(commentUserBean);
    }

    @Override
    @Transactional
    public void updatePassWord(String userName, String passWord) {
        CommentUserBean bean = new CommentUserBean();
        QueryWrapper<CommentUserBean> queryWrapper = new QueryWrapper<>();
        bean.setPassWord(SecureUtil.md5(passWord + MessageConst.PASSWORD_SALT));
        queryWrapper.eq("USER_EMAIL",userName);
        commentUserMapper.update(bean,queryWrapper);
    }

    @Override
    public JSONObject validRegister(CommentUserBean commentUserBean) {
        JSONObject jsonObject = new JSONObject();
        if(StrUtil.isBlank(commentUserBean.getUserEmail())) {
            jsonObject.put("errorMsg","请输入邮件地址");
            return jsonObject;
        }
        if(StrUtil.isBlank(commentUserBean.getVerifyCode())) {
            jsonObject.put("errorMsg","请输入验证码");
            return jsonObject;
        }
        if(StrUtil.isBlank(commentUserBean.getPassWord())) {
            jsonObject.put("errorMsg","请输入密码");
            return jsonObject;
        }
        if(StrUtil.isBlank(commentUserBean.getRepass())){
            jsonObject.put("errorMsg","请输入确认密码");
            return jsonObject;
        }
        if(StrUtil.isBlank(commentUserBean.getVerifyCode())) {
            jsonObject.put("errorMsg","请输入邮箱验证码");
            return jsonObject;
        }
        //业务校验
        //昵称和邮件唯一性校验
        String cacheVerCode =  cacheService.getCacheInfoByCode(SysConstant.MAIL_CODE_CACHE + commentUserBean.getUserEmail() + commentUserBean.getVerifyCode());
        if(StrUtil.isBlank(cacheVerCode)) {
            jsonObject.put("errorMsg","验证码已过期,请重新获取");
            return jsonObject;
        }
        if(!StrUtil.equalsAnyIgnoreCase(commentUserBean.getVerifyCode(), cacheVerCode)) {
            jsonObject.put("errorMsg","请输入正确的验证码");
            return jsonObject;
        }
        if(!StrUtil.equals(commentUserBean.getPassWord(),commentUserBean.getRepass())){
            jsonObject.put("errorMsg","两次输入密码不一致");
            return jsonObject;
        }

        return jsonObject;
    }

    @Override
    public boolean isExists(String userEmail, String userNick) {
        boolean resFlag = false; //默认不存在可以注册
        QueryWrapper<CommentUserBean> queryWrapper = new QueryWrapper<>();
        if(StrUtil.isNotBlank(userEmail)) {
            queryWrapper.eq("USER_EMAIL",userEmail);
        }
        if(StrUtil.isNotBlank(userNick)) {
            queryWrapper.eq("USER_NICK",userNick);
        }
        Integer count = commentUserMapper.selectCount(queryWrapper);
        if(count > 0) {
            resFlag = true;
            return resFlag;
        }
        return resFlag;
    }

    @Override
    public CommentUserBean queryUserById(String userId) {
        QueryWrapper<CommentUserBean> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_ID",userId);
        queryWrapper.eq("USER_STATE",MessageConst.ENABLED);
        return commentUserMapper.selectOne(queryWrapper);
    }

}
